package com.ymatou.iapi.trading.sellerquery.testcase;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import com.ymatou.iapi.trading.sellerquery.parameter.GetRelatedOrderInfosBean;
import com.ymatou.iapi.trading.sellerquery.parameter.resp.GetRelatedOrderInfosResp;
import com.ymatou.query.seller.trading.api.parameter.Ymt_Order;
import com.ymatou.query.seller.trading.api.parameter.Ymt_OrderInfo;
import com.ymatou.query.seller.trading.api.service.OrderCreate;
import com.ymatou.query.trading.api.parameter.OrderConverter;
import com.ymt.core.tool.FormatUtil;
import com.ymt.core.tool.Logger;
import com.ymt.utils.annotation.TestCase;
import com.ymt.utils.annotation.TestSuite;
import com.ymt.utils.tag.P1;
import com.ymt.utils.tag.P3;
import com.ymttest.database.model.OrderInfoForRelated;
import com.ymttest.database.model.OrderItemInfoForRelated;
import com.ymttest.database.sqlwapper.DefaultWapper;
import com.ymttest.utils.DataUtil;
import com.ymttest.utils.EnvSetup;
import com.ymttest.utils.constant.ECode;

/**
 * 获取相关订单详情Call FreeMaker Template自动生成代码
 */
@SuppressWarnings("rawtypes")
@TestSuite
public class Ts_GetRelatedOrderInfos {

	private static GetRelatedOrderInfosBean groisBean;
	private static com.ymatou.query.seller.trading.api.service.GetRelatedOrderInfosCall groisCall;
//	private static com.ymatou.iapi.trading.sellerquery.service.GetRelatedOrderInfosCall groisCall;
	private List<Ymt_Order> orders;
	private List<Ymt_OrderInfo> orderInfos;

	@BeforeClass
	public static void setUp() {
		Logger.createResultFile("获取相关订单详情");
	}

	@Before
	public void caseUp() {
		groisBean = new GetRelatedOrderInfosBean();
		groisCall = new com.ymatou.query.seller.trading.api.service.GetRelatedOrderInfosCall();
//		groisCall = new com.ymatou.iapi.trading.sellerquery.service.GetRelatedOrderInfosCall();
		orders = new ArrayList<Ymt_Order>();
		orderInfos = new ArrayList<Ymt_OrderInfo>();
	}

	@AfterClass
	public static void tearDown() {
		Logger.generateResult(groisCall.getOpurl());
	}

	@After
	public void caseDown() {
		Logger.end();
	}
	
	private void verify(){
		GetRelatedOrderInfosResp expectResponse = new GetRelatedOrderInfosResp();
		ConstructExpectedResponse(expectResponse);
		GetRelatedOrderInfosResp actualResponse = groisCall.getRelatedOrderInfosResp();
		List<OrderInfoForRelated> expects = expectResponse.getOrderInfoList();
		List<OrderInfoForRelated> actuals = actualResponse.getOrderInfoList();
		if(expects == null){
			DataUtil.verify(expects, actuals, "验证OrderInfoList == null");
		}else{
			boolean sameSize = expects.size()==actuals.size();
			DataUtil.verify(expects.size(), actuals.size(), "验证OrderInfoList.size()");
			if(sameSize){
				for(int i=0;i<expects.size();i++){
					OrderInfoForRelated expect = expects.get(i);
					OrderInfoForRelated actual = actuals.get(i);
					verifyOrderInfoForRelated(expect, actual);
				}
			}
		}
	}
	
	private void verifyOrderInfoForRelated(OrderInfoForRelated expect,OrderInfoForRelated actual){
		DataUtil.verify(expect.getOrderId(), actual.getOrderId(),"验证OrderId");
		DataUtil.verify(expect.getTradingStatus(), actual.getTradingStatus(),"验证TradingStatus");
		DataUtil.verify(expect.getUserId(), actual.getUserId(),"验证UserId");
		DataUtil.verify(expect.getBuyerId(), actual.getBuyerId(),"验证BuyerId");
		DataUtil.verify(expect.getBuyerLoginId(), actual.getBuyerLoginId(),"验证BuyerLoginId");
		DataUtil.verify(expect.getSellerLoginId(), actual.getSellerLoginId(),"验证SellerLoginId");
		DataUtil.verify(expect.getPayableAmount(), actual.getPayableAmount(),"验证PayableAmount");
		DataUtil.verify(expect.getYmtCouponCode(), actual.getYmtCouponCode(),"验证YmtCouponCode");
		DataUtil.verify(expect.getYmtCouponAmount(), actual.getYmtCouponAmount(),"验证YmtCouponAmount");
		DataUtil.verify(expect.getSellerCouponCode(), actual.getSellerCouponCode(),"验证SellerCouponCode");
		DataUtil.verify(expect.getSellerCouponAmount(), actual.getSellerCouponAmount(),"验证SellerCouponAmount");
		DataUtil.verify(expect.getMainOrderId(), actual.getMainOrderId(),"验证MainOrderId");
		DataUtil.verify(expect.getPromotionReducedAmount(), actual.getPromotionReducedAmount(),"验证PromotionReducedAmount");
		List<OrderItemInfoForRelated> exps = expect.getOrderItemInfoList();
		List<OrderItemInfoForRelated> acts = actual.getOrderItemInfoList();
		if(exps == null){
			DataUtil.verify(exps, acts, "验证OrderItemInfoList == null");
		}else{
			boolean sameSize = exps.size() == acts.size();
			DataUtil.verify(exps.size(), acts.size(), "验证OrderItemInfoList.size()");
			if(sameSize){
				for(OrderItemInfoForRelated exp : exps){
					boolean exist = acts.stream().anyMatch(x->x.toString().equals(exp.toString()));
					DataUtil.verify(true, exist, "验证OrderItemInfoList中是否存在\n"+exp.toString()+"\n的记录");
				}
			}
		}
	}
	
	private void ConstructExpectedResponse(GetRelatedOrderInfosResp response) {
		execute(groisBean.getOrderId());
		List<OrderInfoForRelated> orderInfoList = new ArrayList<>();
		OrderInfoForRelated r = null;
		if (!DataUtil.isNullOrEmpty(orders)) {
			for (Ymt_Order order : orders) {
				r = new OrderInfoForRelated();
				r.setBuyerId(order.getiBuyerId());
				r.setBuyerLoginId(order.getsBuyerLoginId());
				r.setMainOrderId((long) order.getiMainOrderId());
				r.setOrderId(order.getiOrderId());
				r.setPayableAmount(order.getfPayableAmount());
				r.setPromotionReducedAmount(order.getfSellerPromotionAmount());
				r.setSellerCouponAmount(order.getfSellerCouponAmount());
				r.setSellerCouponCode(order.getsSellerCouponCode());
				r.setSellerLoginId(order.getsSellerLoginId());
				r.setTradingStatus(order.getiTradingStatus());
				r.setUserId(order.getiUserId());
				r.setYmtCouponAmount(order.getfYmtCouponAmount());
				r.setYmtCouponCode(order.getsYmtCouponCode());
				List<OrderItemInfoForRelated> orderItemInfoList = new ArrayList<OrderItemInfoForRelated>();
				List<Ymt_OrderInfo> matchs = orderInfos.stream().filter(x->x.getiOrderId()==order.getiOrderId()).collect(Collectors.toList());
				if (!DataUtil.isNullOrEmpty(matchs)) {
					for (Ymt_OrderInfo o : matchs) {
						OrderItemInfoForRelated ir = new OrderItemInfoForRelated();
						ir.setAmount(o.getiAmount());
						ir.setCatalogId(o.getsCatalogId());
						ir.setDiscount(o.getfDiscount());
						ir.setFreight(o.getfFreight());
						ir.setProductId(o.getsProductId());
						ir.setProductPrice(o.getfProductPrice());
						ir.setPromotion(OrderConverter.GetPromotion(o));
						ir.setSellerCouponAmount(o.getfSellerCouponAmount());
						ir.setSupportRtnWithoutReason(o
								.isbSupportRtnWithoutReason());
						ir.setTitle(o.getsTitle());
						ir.setYmtCouponAmount(o.getfYmtCouponAmount());
						orderItemInfoList.add(ir);
					}
				}
				r.setOrderItemInfoList(orderItemInfoList);
				orderInfoList.add(r);
			}
		}
		response.setOrderInfoList(orderInfoList);
	}
	
	private void execute(int orderId){
		DefaultWapper db = new DefaultWapper();
		List<Map> list1 = db.executeSql(getSql1(orderId));
		List<Map> list2 = db.executeSql(getSql2(orderId));
		convertResult(list1, list2);
	}
	
	private void convertResult(List<Map> list1,List<Map> list2){
		if(false == DataUtil.isNullOrEmpty(list1)){
			for(Map m:list1){
				Ymt_Order o = new Ymt_Order();
				DataUtil.mapToBean(o, m);
				orders.add(o);
			}
		}
		if(false == DataUtil.isNullOrEmpty(list2)){
			for(Map m:list2){
				Ymt_OrderInfo o = new Ymt_OrderInfo();
				DataUtil.mapToBean(o, m);
				orderInfos.add(o);
			}
		}
	}

	private String baseSql(int orderId) {
		return "DECLARE @MainOrderId INT;"
				+ " DECLARE @OrdersTable TABLE(iOrderId INT NOT NULL);"
				+ " SELECT @MainOrderId = iMainOrderId FROM Ymt_Orders ( NOLOCK ) WHERE iOrderId = "
				+ orderId
				+ ";"
				+ " INSERT INTO @OrdersTable SELECT iOrderid FROM Ymt_Orders ( NOLOCK ) WHERE iMainOrderId = @MainOrderId;";
	}

	private String getSql1(int orderId) {
		String sql1 = "SELECT a.iOrderId, a.iTradingStatus, a.iUserId, a.iBuyerId, a.sBuyerLoginId,"
				+ " a.sSellerLoginId, a.fPayableAmount, a.sYmtCouponCode, a.fYmtCouponAmount,"
				+ " a.sSellerCouponCode, a.fSellerCouponAmount, a.iMainOrderId, a.fSellerPromotionAmount"
				+ " FROM Ymt_Orders a ( NOLOCK )"
				+ "   JOIN @OrdersTable b ON a.iOrderId = b.iOrderId;";
		return baseSql(orderId) + sql1;
	}

	private String getSql2(int orderId) {
		String sql2 = "SELECT a.iOrderId, a.sProductId, a.sCatalogId, a.sTitle,"
				+ " a.iAmount, a.fYmtCouponAmount, a.fSellerCouponAmount, a.fFreight,"
				+ " a.fDiscount, a.fProductPrice, a.fSellerPromotionAmount, a.bSupportRtnWithoutReason"
				+ " , c.promotionId,c.promotionName,c.promotionType,"
				+ " c.matchCondition,c.promotionValue,c.reducedAmount"
				+ " FROM Ymt_OrderInfo a ( NOLOCK )"
				+ " JOIN @OrdersTable b ON a.iOrderId = b.iOrderId"
				+ " LEFT JOIN Ymt_SellerPromotion(nolock) c on c.OrderInfoId = a.sOrderInfoId";
		return baseSql(orderId) + sql2;
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_GetRelatedOrderInfos_001() {
		Logger.start(true, "订单包含多个商品, 根据OrderId获取相关订单详情,成功");
		try {
			Logger.comment("准备测试订单数据");
			int sellerId = Integer.valueOf(EnvSetup.getData("SellerId"));
			int userId = Integer.valueOf(EnvSetup.getData("BuyUserId"));
			OrderCreate o = new OrderCreate();
			o.setProductCount(3);
			int orderId = o.create1_M2cOrder(userId, sellerId).getiOrderId();
			Thread.sleep(500l);
			Logger.comment("准备测试订单数据完成");
			
			groisBean.setOrderId(orderId);
			String s = FormatUtil.beanToHttpString(groisBean, true, false);
			groisCall.setData(s);
			groisCall.callService();
			Logger.verifyEquals(ECode.SUCCESS, groisCall.getCode(), "验证Code");
			verify();
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_GetRelatedOrderInfos_002() {
		Logger.start(false, "OrderId为空，获取相关订单详情,失败");
		try {
			String s = FormatUtil.beanToHttpString(groisBean, true, false);
			groisCall.setData(s);
			groisCall.callService();
			Logger.verifyEquals(ECode.SUCCESS, groisCall.getCode(), "验证Code");
			verify();
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_GetRelatedOrderInfos_003() {
		Logger.start(false, "OrderId不存在，获取相关订单详情为空,成功");
		try {
			int orderId = 404;
			groisBean.setOrderId(orderId);
			String s = FormatUtil.beanToHttpString(groisBean, true, false);
			groisCall.setData(s);
			groisCall.callService();
			Logger.verifyEquals(ECode.SUCCESS, groisCall.getCode(), "验证Code");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_GetRelatedOrderInfos_004() {
		Logger.start(true, "订单包含一个商品, 根据OrderId获取相关订单详情,成功");
		try {
			Logger.comment("准备测试订单数据");
			int sellerId = Integer.valueOf(EnvSetup.getData("SellerId"));
			int userId = Integer.valueOf(EnvSetup.getData("BuyUserId"));
			OrderCreate o = new OrderCreate();
			o.setProductCount(1);
			int orderId = o.create1_M2cOrder(userId, sellerId).getiOrderId();
			Thread.sleep(500l);
			Logger.comment("准备测试订单数据");
			
			groisBean.setOrderId(orderId);
			String s = FormatUtil.beanToHttpString(groisBean, true, false);
			groisCall.setData(s);
			groisCall.callService();
			Logger.verifyEquals(ECode.SUCCESS, groisCall.getCode(), "验证Code");
			verify();
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_GetRelatedOrderInfos_005() {
		Logger.start(true, "sellerquery2冒烟测试");
		try {
			groisBean.setOrderId(112477943);
			String s = FormatUtil.beanToHttpString(groisBean, true, true);
			groisCall.setData(s);
			groisCall.callService();
			Logger.verifyEquals(ECode.SUCCESS, groisCall.getCode(), "验证Code");
			verify();
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	
}
